package com.ruoyi.nsh.util;

import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class StringUtil {
	// Static format objects
	private static SimpleDateFormat dateFormat = new SimpleDateFormat();

	private static DecimalFormat numberFormat = new DecimalFormat();

	/**
	 * <DL>
	 * <DT><B> 合并字符串数组 </B></DT>
	 * <p>
	 * <DD> 将两个字符串数组合并成一个 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param arrayA
	 *            字符串数组A
	 * @param arrayB
	 *            字符串数组A
	 * @return 合并后的数组
	 */
	public static String[] combineArray(String[] arrayA, String[] arrayB) {
		if (arrayA == null) {
			return arrayB;
		}
		if (arrayB == null) {
			return arrayA;
		}
		String[] array = new String[arrayA.length + arrayB.length];
		System.arraycopy(arrayA, 0, array, 0, arrayA.length);
		System.arraycopy(arrayB, 0, array, arrayA.length, arrayB.length);
		return array;
	}

	/**/
	/**
	 * <DL>
	 * <DT><B> 填充 </B></DT>
	 * <p>
	 * <DD> 用字符iChar填充满字符串sBufData到isBufLen位，isBufLen为负数左靠齐，isBufLen为正数右靠齐 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param sBufData 被填充的字符串
	 * @param iChar 填充字符
	 * @param isBufLen 填充长度，为负数左靠齐，为正数右靠齐
	 * @return 填充后的字符串
	 */
	public static String fixFill(String sBufData, String iChar, int isBufLen) {
		assert (sBufData != null);
		assert (iChar != null);

		String sRetMsg;
		byte bObjData[];
		byte bBufData[];
		try
		{
			bBufData = sBufData.getBytes("GBK");
		} catch (UnsupportedEncodingException e)
		{
			bBufData = sBufData.getBytes();
		}
		byte bCharData[];
		try
		{
			bCharData = iChar.getBytes("GBK");
		} catch (UnsupportedEncodingException e)
		{
			bCharData = iChar.getBytes();
		}
		int iLen;

		int sBufDataLen = bBufData.length;
		if (isBufLen < 0) {
			iLen = 0 - isBufLen;
			bObjData = new byte[iLen];
			if (sBufDataLen > iLen) {
				sBufDataLen = iLen;
			}
		} else {
			iLen = isBufLen;
			bObjData = new byte[isBufLen];
			if (sBufDataLen > iLen) {
				int iStart = sBufDataLen - iLen;
				for (int i = 0; i < iLen; i++) {
					bBufData[i] = bBufData[i + iStart];
				}
				sBufDataLen = iLen;
			}
		}
		if (isBufLen < 0) {
			for (int i = 0; i < sBufDataLen; i++) {
				bObjData[i] = bBufData[i];
			}
			for (int i = sBufDataLen; i < iLen; i++) {
				bObjData[i] = bCharData[0];
			}
		} else {
			int iStart = isBufLen - sBufDataLen;
			for (int i = 0; i < iStart; i++) {
				bObjData[i] = bCharData[0];
			}
			for (int i = 0; i < sBufDataLen; i++) {
				bObjData[iStart + i] = bBufData[i];
			}
		}
		/*
		 * if (isBufLen < 0) { bObjData = hzFixFill(bObjData, iLen); }
		 */
		sRetMsg = new String(bObjData);
		return sRetMsg;
	}

	/**
	 * <DL>
	 * <DT><B> 获得当前日期 </B></DT>
	 * <p>
	 * <DD>
	 *
	 * </DD>
	 * </DL>
	 * <p>
	 *
	 * @param date
	 *            日期
	 * @param dateFormatPattern
	 *            日期格式，如果写入null,格式为yyyy-MM-dd hh:mm:ss
	 * @return 根据指定日期格式得到的日期
	 * @throws ParseException
	 */
	public static String getDate(Date date, String dateFormatPattern)
			throws ParseException {
		if (date == null) {
			Date sysdate = new Date();
			date = sysdate;
		}
		if (dateFormatPattern == null) {
			dateFormatPattern = "yyyy-MM-dd hh:mm:ss";
		}
		dateFormat = new SimpleDateFormat(dateFormatPattern);
		return dateFormat.format(date);
	}

	/**
	 * <DL>
	 * <DT><B> 获得当前日期 </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param dateFormatPattern
	 *            日期格式，如果写入null,格式为yyyy-MM-dd hh:mm:ss
	 * @throws ParseException
	 */
	public static String getSysDate(String dateFormatPattern)
			throws ParseException {
		Date sysdate = new Date();
		if (dateFormatPattern == null) {
			dateFormatPattern = "yyyy-MM-dd hh:mm:ss";
		}
		dateFormat = new SimpleDateFormat(dateFormatPattern);
		return dateFormat.format(sysdate);
	}

	/**
	 * <DL>
	 * <DT><B> Returns true if the specified date string represents a valid
	 * date in the specified format. </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param dateString
	 *            dateString a String representing a date/time.
	 * @param dateFormatPattern
	 *            dateFormatPattern a String specifying the format to be used
	 *            when parsing the dateString. The pattern is expressed with the
	 *            pattern letters defined for the java.text.SimpleDateFormat
	 *            class.
	 * @return true if valid, false otherwise
	 */
	public static boolean isValidDate(String dateString,
									  String dateFormatPattern) {
		assert (dateString != null);
		assert (dateFormatPattern != null);
		Date validDate = null;
		synchronized (dateFormat) {
			try {
				dateFormat.applyPattern(dateFormatPattern);
				dateFormat.setLenient(false);
				validDate = dateFormat.parse(dateString);
			} catch (ParseException e) {
				// Ignore and return null
			}
		}
		return validDate != null;
	}

	/**
	 * <DL>
	 * <DT><B> Returns true if the email string contains an at sign ("@") and
	 * at least one dot ("."), i.e. "hans@gefionsoftware.com" is accepted but
	 * "hans@gefionsoftware" is not. Note! This rule is not always correct (e.g.
	 * on an intranet it may be okay with just a name) and does not gurantee a
	 * valid Internet email address but it takes care of the most obvious
	 * Internet mail address format errors. </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param emailAddrString
	 *            emailAddrString a String representing an email address
	 * @return true if valid, false otherwise
	 */
	public static boolean isValidEmailAddr(String emailAddrString) {
		boolean isValid = false;
		if (emailAddrString != null && emailAddrString.indexOf("@") != -1
				&& emailAddrString.indexOf(".") != -1) {
			isValid = true;
		}
		return isValid;
	}

	/**
	 * Returns true if the specified number string represents a valid integer in
	 * the specified range.
	 *
	 * @param numberString
	 *            a String representing an integer
	 * @param min
	 *            the minimal value in the valid range
	 * @param max
	 *            the maximal value in the valid range
	 * @return true if valid, false otherwise
	 */
	public static boolean isValidInteger(String numberString, long min, long max) {
		assert (numberString != null);
		Long validLong = null;
		try {
			Number aNumber = numberFormat.parse(numberString);
			long aLong = aNumber.longValue();
			if (aLong >= min && aLong <= max) {
				validLong = new Long(aLong);
			}
		} catch (ParseException e) {
			// Ignore and return null
		}
		return validLong != null;
	}

	public static boolean isValidNumber(String numberString, double min,
										double max) {
		assert (numberString != null);

		boolean validNumber = false;
		try {
			Number aNumber = toNumber(numberString);
			double anDouble = aNumber.doubleValue();
			if (anDouble >= min && anDouble <= max) {
				validNumber = true;
			}
		} catch (ParseException e) {
			// Ignore and return null
		}
		return validNumber;
	}

	public static boolean isValidNumber(String numberString, String min,
										String max) {
		assert (numberString != null);
		assert (min != null);
		assert (max != null);
		boolean validNumber = false;
		try {
			Number aNumber = toNumber(numberString);
			Number nMin = toNumber(min);
			Number nMax = toNumber(max);
			double anDouble = aNumber.doubleValue();
			double dMin = nMin.doubleValue();
			double dMax = nMax.doubleValue();
			if (anDouble >= dMin && anDouble <= dMax) {
				validNumber = true;
			}
		} catch (ParseException e) {
			// Ignore and return null
		}
		return validNumber;
	}

	/**
	 * <DL>
	 * <DT><B> Returns true if the specified string matches a string in the set
	 * of provided valid strings, ignoring case if specified. </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param value
	 *            the String validate
	 * @param validStrings
	 *            an array of valid Strings
	 * @param ignoreCase
	 *            if true, case is ignored when comparing the value to the set
	 *            of validStrings
	 * @return true if valid, false otherwise
	 */
	public static boolean isValidString(String value, String[] validStrings,
										boolean ignoreCase) {
		boolean isValid = false;
		for (int i = 0; validStrings != null && i < validStrings.length; i++) {
			if (ignoreCase) {
				if (validStrings[i].equalsIgnoreCase(value)) {
					isValid = true;
					break;
				}
			} else {
				if (validStrings[i].equals(value)) {
					isValid = true;
					break;
				}
			}
		}
		return isValid;
	}

	/**
	 * <DL>
	 * <DT><B> Replaces one string with another throughout a source string.
	 * </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @para in the source String
	 * @para from the sub String to replace
	 * @para to the sub String to replace with
	 * @return 替换后的结果
	 */
	public static String replaceInString(String in, String from, String to) {
		if (in == null || from == null || to == null) {
			return in;
		}

		StringBuffer newValue = new StringBuffer();
		char[] inChars = in.toCharArray();
		int inLen = inChars.length;
		char[] fromChars = from.toCharArray();
		int fromLen = fromChars.length;

		for (int i = 0; i < inLen; i++) {
			if (inChars[i] == fromChars[0] && (i + fromLen) <= inLen) {
				boolean isEqual = true;
				for (int j = 1; j < fromLen; j++) {
					if (inChars[i + j] != fromChars[j]) {
						isEqual = false;
						break;
					}
				}
				if (isEqual) {
					newValue.append(to);
					i += fromLen - 1;
				} else {
					newValue.append(inChars[i]);
				}
			} else {
				newValue.append(inChars[i]);
			}
		}
		return newValue.toString();
	}

	/**
	 * <DL>
	 * <DT><B> 往字节数组第nStart位开始填充另一个byte 数组 </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param bObjData
	 * @param nStart
	 * @param sSrcData
	 */
	public static byte[] setBytesData(byte bObjData[], int nStart,
									  byte sSrcData[]) {
		assert (bObjData != null);
		assert (sSrcData != null);
		int nCount;
		nCount = sSrcData.length;
		for (int i = 0; i < nCount; i++)
			bObjData[nStart + i] = sSrcData[i];
		return bObjData;
	}

	public static String toHexTable(byte byteSrc[], int lengthOfLine)
	{
		return toHexTable(byteSrc, lengthOfLine, 7);
	}

	public static String toHexTable(byte byteSrc[], int lengthOfLine, int flag)
	{
		StringBuffer hexTableBuffer = new StringBuffer(256);
		int lineCount = byteSrc.length / lengthOfLine;
		int totalLen = byteSrc.length;
		if(byteSrc.length % lengthOfLine != 0){
			lineCount++;
		}
		for (int lineNumber = 0; lineNumber < lineCount; lineNumber++)
		{
			int startPos = lineNumber * lengthOfLine;
			byte lineByte[] = new byte[Math.min(lengthOfLine, totalLen
					- startPos)];
			System.arraycopy(byteSrc, startPos, lineByte, 0, lineByte.length);
			int flagA = flag & 4;
			if (4 == flagA)
			{
				int count = lengthOfLine * lineNumber;
				String addrStr = Integer.toString(count,16);
				int len = addrStr.length();
				for (int i = 0; i < 8 - len; i++){
					hexTableBuffer.append('0');
				}

				hexTableBuffer.append(addrStr);
				hexTableBuffer.append("h: ");
			}
			int flagB = flag & 2;
			if (2 == flagB)
			{
				StringBuffer byteStrBuf = new StringBuffer();
				for (int i = 0; i < lineByte.length; i++)
				{
					String num = Integer.toHexString(lineByte[i] & 0xff);
					if (num.length() < 2){
						byteStrBuf.append('0');
					}
					byteStrBuf.append(num);
					byteStrBuf.append(' ');
				}
				hexTableBuffer.append(fixFill(byteStrBuf.toString()," ", 48));
				hexTableBuffer.append("; ");
			}
			int flagC = flag & 1;
			if (1 == flagC)
			{
				for (int i = 0; i < lineByte.length; i++)
				{
					char c = (char) lineByte[i];
					if (c < '!'){
						c = '.';
					}
					try
					{
						if (c >= '\240' && i < lineByte.length - 1)
						{
							char c2 = (char) lineByte[i + 1];
							if (c2 >= '\240')
							{
								String str = new String(lineByte, i, 2);
								hexTableBuffer.append(str);
								i++;
								continue;
							}
						}
					} catch (Exception e)
					{
						e.printStackTrace();
					}
					hexTableBuffer.append("");
					hexTableBuffer.append(c);
				}

			}
			if (lineNumber >= lineCount - 1){
				break;
			}
			hexTableBuffer.append('\n');
		}

		return hexTableBuffer.toString();
	}

	/**
	 * 按照指定的字节位置分割一个字符串为一个含有两个字符串的数组
	 *
	 * @param source
	 *            待分割的字符串
	 * @param bytePosition
	 *            字节位置
	 * @return 分割后的字符串数组
	 */
	public static String[] splitAtBytePosition(String source, int bytePosition) {
		int byteWidth = 0;
		int charCursor = 0;
		for (; charCursor < source.length(); charCursor++) {
			char c = source.charAt(charCursor);
			int width = c > 0xff ? 2 : 1;
			if (byteWidth + width > bytePosition) {
				break;
			}
			byteWidth += width;
		}
		String prefix = source.substring(0, charCursor);
		String suffix = source.substring(charCursor);
		return new String[] { prefix, suffix };
	}

	/**
	 * <DL>
	 * <DT><B> Converts a String to a Date, using the specified pattern. (see
	 * java.text.SimpleDateFormat for pattern description) </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @param dateString
	 *            the String to convert
	 * @param dateFormatPattern
	 *            the pattern, 默认格式yyyy-MM-dd hh:mm:ss
	 * @return the corresponding Date
	 * @throws ParseException
	 *             if the String doesn't match the pattern
	 */
	public static Date toDate(String dateString, String dateFormatPattern)
			throws ParseException {
		assert (dateString != null);
		Date date = null;
		if (dateFormatPattern == null) {
			dateFormatPattern = "yyyy-MM-dd hh:mm:ss";
		}
		synchronized (dateFormat) {
			dateFormat.applyPattern(dateFormatPattern);
			dateFormat.setLenient(false);
			date = dateFormat.parse(dateString);
		}
		return date;
	}

	/**
	 * <DL>
	 * <DT><B> Converts a String to a Number, using the specified pattern. (see
	 * java.text.NumberFormat for pattern description) </B></DT>
	 * <p>
	 * <DD> 默认############.## </DD>
	 * </DL>
	 * <p>
	 *
	 * @para numString the String to convert
	 * @return the corresponding Number
	 * @throws ParseException
	 *             if the String doesn't match the pattern
	 */
	public static Number toNumber(String numString) throws ParseException {
		assert (numString != null);
		Number number = null;
		String numFormatPattern = "############.##";
		synchronized (numberFormat) {
			numberFormat.applyPattern(numFormatPattern);
			number = numberFormat.parse(numString);
		}
		return number;
	}

	/**
	 * <DL>
	 * <DT><B> Converts a String to a Number, using the specified pattern. (see
	 * java.text.NumberFormat for pattern description) </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @para numString the String to convert
	 * @para numFormatPattern the pattern， 默认############.##
	 * @return the corresponding Number
	 * @throws ParseException
	 *             if the String doesn't match the pattern
	 */
	public static Number toNumber(String numString, String numFormatPattern)
			throws ParseException {
		assert (numString != null);
		Number number = null;
		if (numFormatPattern == null) {
			numFormatPattern = "############.##";
		}
		synchronized (numberFormat) {
			numberFormat.applyPattern(numFormatPattern);
			number = numberFormat.parse(numString);
		}
		return number;
	}

	public static String toNumberString(String numString) throws ParseException {
		String number = "0";
		Number num = toNumber(numString);
		String numFormatPattern = "###,###,###,###.##";
		synchronized (numberFormat) {
			numberFormat.applyPattern(numFormatPattern);
			number = numberFormat.format(num);
		}
		return number;
	}

	/**
	 * <DL>
	 * <DT><B> 更改数字字符串的格式 </B></DT>
	 * <p>
	 * <DD> 详细介绍 </DD>
	 * </DL>
	 * <p>
	 *
	 * @para numString 待转换的字符串
	 * @para numFormatPattern 默认###,###,###,###.##
	 * @throws ParseException
	 */
	public static String toNumberString(String numString,
										String numFormatPattern) throws ParseException {
		String number = "0";
		Number num = toNumber(numString);
		if (numFormatPattern == null) {
			numFormatPattern = "###,###,###,###.##";
		}
		synchronized (numberFormat) {
			numberFormat.applyPattern(numFormatPattern);
			number = numberFormat.format(num);
		}
		return number;
	}

	/**
	 * 处理空值
	 * @param str
	 * @return
	 */
	public static String dealNull(String str){
		if(str==null) return null;
		return str;
	}

	public static String get18Lc(String identifyCard){
		String retId="";
		String id17="";
		int sum=0;
		int y=0;
		//定义数据加权因子
		int[] sf={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
		//定义数组存放校验码
		String[] cc={"1","0","X","9","8","7","6","5","4","3","2"};
		//在原15位身份证的第6位数后面查询19
		id17=identifyCard.substring(0, 6)+"19"+identifyCard.substring(6);
		for(int i=0;i<17;i++){
			sum=sum+Integer.valueOf(id17.substring(i,i+1))*sf[i];
		}
		y=sum%11;
		retId=id17+cc[y];
		return retId;
	}

	/**
	 * 18位转15位身份证
	 * @param identifyCard
	 * @return
	 */
	public static String  get15Lc(String identifyCard){
		return identifyCard.substring(0,6)+identifyCard.substring(8,17);
	}

	public static void main(String[] args) {
		System.out.println(get18Lc("321081630224337"));
		System.out.println(get15Lc(get18Lc("321081630224337")));
	}
}
